package uniandes.moviles.antid.mundo;

import java.util.ArrayList;
import java.util.Date;

/**
 * A  dyslexia professional that treats patients. The professionals can:
 * <ul> 
 * <li>Create routines.</li>
 * <li>Assign routines to patients.</li>
 * <li>Remove routines.</li>
 * <li>Modify routines.</li> 
 * @author Julio Mendoza
 *
 */
public class Professional extends User
{
	/**
	 * Identifier of that specifies the role of the user is a professional.
	 * This is used in order to give or restrict access to certain processes of the application, available 
	 * depending on the role of the user.
	 */
	private static final int ROLE = 1;
	
	/**
	 * Routines created by the professional.
	 */
	private ArrayList<Routine> routines;
	
	/**
	 * Patients the professional is treating.
	 */
	private ArrayList<Patient> patients;
	
	/**
	 * Creates a new professional.	
	 * @param manager The persistence manager to read or write in the database.
	 * @throws Exception if there are registration errors.
	 */
	public Professional(PersistenceManager manager)
	{
		super(manager);
		routines = new ArrayList<Routine>();
		patients = new ArrayList<Patient>();
		
	}
	
	/**
	 * Searches a patient by the given user name.
	 * @param puserName The patient's user name.
	 * @return p the found patient.
	 * @throws Exception if the patient to find is not on the patients list.
	 */
	public Patient searchPatient(String puserName) throws Exception
	{
		Patient p = null;
		boolean found = false;
		for(int i = 0; i < patients.size() && !found; i ++)
		{
			Patient patient = patients.get(i);
			if(patient.getUserName().equals(puserName))
			{
				p = patient;
				found = true;
			}
		}
		if(!found)
		{
			throw new Exception("The patient is not in your patient list.");
		}
		return p;
	}
	
	/**
	 * Searches a routine in the routine list by the given id.
	 * @param id The id of the routine to search.
	 * @return r
	 * @throws Exception if the routine is not on the user's routine list.
	 */
	public Routine searchRoutine(int id) throws Exception
	{
		Routine r = null;
		boolean found = false;
		for(int i = 0; i < routines.size() && !found; i++)
		{
			Routine routine = routines.get(i);
			if(routine.getId()==id)
			{
				r = routine;
				found = true;
			}
		}
		if(!found)
		{
			throw new Exception("the routine is not on your routines list.");
		}
		return r;
	}
	
	/**
	 * Sets the routine of a patient.
	 * @param puserName
	 * @param id
	 * @throws Exception
	 */
	public void setPatientRoutine(String puserName, int id) throws Exception
	{
		try 
		{
			Patient p = searchPatient(puserName);
			Routine r = searchRoutine(id);
			p.setRoutine(r);
		}
		catch (Exception e) 
		{
			throw new Exception("the routine could not be added to the patient " + puserName + e.getMessage());
		}		
	}
	
	/**
	 * Adds a given exercise to a routine
	 * @param exercise
	 * @param id
	 * @throws Exception
	 */
	public void addExecriseToRoutine(Exercise exercise, int id) throws Exception
	{
		try
		{
			Routine routine = searchRoutine(id);
			routine.addExercise(exercise.getType(), exercise.getDueDate());
		}
		catch (Exception e) 
		{
			throw new Exception("The exercise could not be addd to the routine. " + e.getMessage());
		}
	}
	
	/**
	 * Returns a new exercise with a given name and a due date.
	 * @param type The type of the exercise to create.
	 * @param dueDate the date the exercise is due.
	 * @return exercise
	 * @throws Exception if the given due date is before the current date.
	 */
	public Exercise createExercise(String type, Date dueDate) throws Exception
	{
		long time = System.currentTimeMillis();
		Date now = new Date(time);
		if(dueDate.before(now))
		{
			throw new Exception("The due date must be after today.");
		}
		Exercise exercise = new Exercise(type, dueDate);
		return exercise;
	}
	
	/**
	 * Creates an exercise routine from a list of exercises. If the exercise list is <b>null</b>, the routine is created without exercises.
	 * @param exercises
	 */
	public void createRoutine(ArrayList<Exercise> exercises)
	{
		Routine routine = new Routine();
		if(exercises == null)
		{
			exercises = new ArrayList<Exercise>();
		}
		routine.setExercises(exercises);
	}

	/**.
	 * Returns the list of created routines of the professional.
	 * @return the routines
	 */
	public ArrayList<Routine> getRoutines() {
		return routines;
	}

	/**
	 * Sets the professional's list of routines.
	 * @param routines the routines to set
	 */
	public void setRoutines(ArrayList<Routine> routines) {
		this.routines = routines;
	}

	/**
	 * Returns the patients list of the professional.
	 * @return the patients
	 */
	public ArrayList<Patient> getPatients() {
		return patients;
	}

	/**
	 * Sets the patients of the professional.
	 * @param patients the patients to set
	 */
	public void setPatients(ArrayList<Patient> patients) {
		this.patients = patients;
	}

	/*
	 * (non-Javadoc)
	 * @see uniandes.moviles.antid.mundo.User#getRole()
	 */
	public int getRole() {
		return ROLE;
	}	
	
}
